package sap.jco.client;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import promis.utility.CommonService;

import com.sap.conn.jco.AbapException;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoFunction;
import com.sap.conn.jco.JCoStructure;
import com.sap.conn.jco.JCoTable;
import com.sap.conn.jco.ext.DestinationDataProvider;

/**
 * @author chatree
 *
 */
public class Connection {
	private static final Logger logging = LoggerFactory.getLogger(Connection.class);
	
	private JCoFunction jcoConnection;
	private JCoFunction function;
	private JCoTable table;
	private JCoStructure structure;	

	/**
	 * @return the structure
	 */
	public JCoStructure getStructure() {
		return structure;
	}

	/** 
	 * @param structure the structure to set
	 */
	public void setStructure(JCoStructure structure) {
		this.structure = structure;
	}

	/**
	 * @return the jcoConnection
	 */
	public JCoFunction getJcoConnection() {
		return jcoConnection;
	}

	/**
	 * @param jcoConnection the jcoConnection to set
	 */
	public void setJcoConnection(JCoFunction jcoConnection) {
		this.jcoConnection = jcoConnection;
	}

	/**
	 * @return the function
	 */
	public JCoFunction getFunction() {
		return function;
	}

	/**
	 * @param function the function to set
	 */
	public void setFunction(JCoFunction function) {
		this.function = function;
	}

	/**
	 * @return the table
	 */
	public JCoTable getTable() {
		return table;
	}

	/**
	 * @param table the table to set
	 */
	public void setTable(JCoTable table) {
		this.table = table;
	}

	/**
	 * 
	 */
	public Connection() {
		// TODO Auto-generated constructor stub
		//System.setProperty("java.library.path", "C:\\AppsInterface\\depoly-jar\\JCo_Tree\\SAPJco 3.0.5\\sapjco3.dll");
	}
	
	public void CreatedJCOConnectionProperty() {
		
		Properties connectProperties = new Properties();
		
        ///JCO ABPA AS POOL 
        connectProperties.clear();
        connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, SAPClientInfo.JCO_ASHOST);
        connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR,  SAPClientInfo.JCO_SYSNR);
        connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, SAPClientInfo.JCO_CLIENT);
        connectProperties.setProperty(DestinationDataProvider.JCO_USER,   SAPClientInfo.JCO_USER);
        connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, SAPClientInfo.JCO_PASSWD);
        connectProperties.setProperty(DestinationDataProvider.JCO_LANG, SAPClientInfo.JCO_LANG);
        
        //connectProperties.setProperty(DestinationDataProvider.JCO_GROUP, SAPClientInfo.JCO_GROUP);    
        //connectProperties.setProperty(DestinationDataProvider.JCO_R3NAME, SAPClientInfo.JCO_R3NAME);               
        
//        connectProperties.put(DestinationDataProvider.JCO_LCHECK, "true");
//        connectProperties.put(DestinationDataProvider.JCO_TRACE, "JCO_CPIC_TRACE_cpicTraceFromFile.txt");
//        connectProperties.put(DestinationDataProvider.JCO_CPIC_TRACE, "JCO_CPIC_TRACE_cpicTraceFromFile.txt");
        
        createDataFile(null, SAPClientInfo.ABAP_AS, "jcoDestination", connectProperties);

//        connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, DestinationDataProvider.JCO_POOL_CAPACITY);
//        connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT,    DestinationDataProvider.JCO_PEAK_LIMIT);
        connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, SAPClientInfo.JCO_POOL_CAPACITY);
        connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT,    SAPClientInfo.JCO_PEAK_LIMIT);
        createDataFile(null, SAPClientInfo.ABAP_AS_POOLED, "jcoDestination", connectProperties);

        
        ///JCO ABPA AS WITHOUT POOL
        connectProperties.clear();
        connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, SAPClientInfo.JCO_ASHOST);
        connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, SAPClientInfo.JCO_SYSNR);
        connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, SAPClientInfo.JCO_CLIENT);
        connectProperties.setProperty(DestinationDataProvider.JCO_USER, SAPClientInfo.JCO_USER);
        connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, SAPClientInfo.JCO_PASSWD);
        connectProperties.setProperty(DestinationDataProvider.JCO_LANG, SAPClientInfo.JCO_LANG);
        
        //connectProperties.setProperty(DestinationDataProvider.JCO_GROUP, SAPClientInfo.JCO_GROUP);    
        //connectProperties.setProperty(DestinationDataProvider.JCO_R3NAME, SAPClientInfo.JCO_R3NAME); 
        
//        connectProperties.put(DestinationDataProvider.JCO_LCHECK, true);
//        connectProperties.put(DestinationDataProvider.JCO_TRACE, "JCO_CPIC_TRACE_cpicTraceFromFile.txt");
//        connectProperties.put(DestinationDataProvider.JCO_CPIC_TRACE, "JCO_CPIC_TRACE_cpicTraceFromFile.txt");
        
        createDataFile(null, SAPClientInfo.ABAP_MS, "jcoDestination", connectProperties);
	}

    private void createDataFile(String path, String name, String suffix, Properties properties)
    {
        if(path == null) 
        	path = "";
        if(path.equals("")) 
        	path = "";
        File cfg = new File(path + name+"."+suffix);
        if(!cfg.exists())
        {
            try
            {
                FileOutputStream fos = new FileOutputStream(cfg, false);
                properties.store(fos, "for tests only !");
                fos.close();
            }
            catch (Exception e)
            {
                throw new RuntimeException("Unable to create the destination file " + cfg.getName(), e);
            }
        }
    }
    
    public void TestedConnectUsingPool() throws JCoException
    {
        JCoDestination destination = JCoDestinationManager.getDestination(SAPClientInfo.ABAP_AS_POOLED);
        destination.ping();
        System.out.println("Attributes:");
        System.out.println(destination.getAttributes());
        System.out.println();
    }
	
	public void TestedConnectUsingWithOutPool() throws JCoException
	{
		System.out.println(SAPClientInfo.ABAP_AS);
        JCoDestination destination = JCoDestinationManager.getDestination(SAPClientInfo.ABAP_AS);
        System.out.println("Attributes:");
        System.out.println(destination.getAttributes());
        System.out.println();
        
        System.out.println(SAPClientInfo.ABAP_MS);
        destination = JCoDestinationManager.getDestination(SAPClientInfo.ABAP_MS);
        System.out.println("Attributes:");
        System.out.println(destination.getAttributes());
        System.out.println();
    
	}
	
	public void JcoTestCompany() throws JCoException {
		
		getJCoFunction("BAPI_COMPANYCODE_GETLIST");
		
		
		JCoTable codes = this.function.getTableParameterList().getTable("COMPANYCODE_LIST");
		
		System.out.println("getNumRows = " + codes.getNumRows());
	        
        for (int i = 0; i < codes.getNumRows(); i++) 
        {
            codes.setRow(i);
            System.out.println(codes.getString("COMP_CODE") + '\t' + codes.getString("COMP_NAME"));
        }
	}
		
	public JCoDestination getJCoConnection() throws JCoException {
		
		try{
			return JCoDestinationManager.getDestination(SAPClientInfo.ABAP_AS_POOLED);	
		}catch(JCoException e){
			try{
				e.printStackTrace();
				CreatedJCOConnectionProperty();
				return JCoDestinationManager.getDestination(SAPClientInfo.ABAP_AS_POOLED);
			}catch(JCoException ex)
			{
				ex.printStackTrace();
				throw ex;
			}
		}
	}
	
	
	public JCoFunction getJCoFunction(String function_name) throws JCoException  {
				
		JCoDestination jcoConnection = this.getJCoConnection();
		JCoFunction function = null;
		if(jcoConnection != null){
			function = jcoConnection.getRepository().getFunction(CommonService.IsNullRString(function_name));
		}
		else
		{
			throw new RuntimeException( function_name +  "nothing in SAP.");
		}
		
		if(function == null)
			throw new RuntimeException( function_name +  " not found in SAP.");
		try
        {
            function.execute(jcoConnection);
            this.function = function;
        }
        catch(AbapException e)
        {
        	e.printStackTrace();
        	logging.error(e.getMessage());
        }
		return function;
	}
	
	public JCoTable getTables(String table_name){
		
		JCoTable table = function.getTableParameterList().getTable(table_name);
		return table;
	}
	
	public boolean isNull(JCoTable table){
		if(!table.isEmpty())
			return false;
		else
			return true;
	}
	
	public JCoStructure getExportStructure(String structure_name){
		
		JCoStructure structure = function.getExportParameterList().getStructure(CommonService.IsNullRString(structure_name));
		
		if(structure != null)
			return structure;
		else
			return null;
	}
	
	public JCoStructure getImportStructure(String structure_name){
		try{
			
			logging.info("structure_name=" + structure_name);
			JCoStructure structure = function.getImportParameterList().getStructure(CommonService.IsNullRString(structure_name));
			
			if(structure != null)
				return structure;
			else
				return null;
			
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	public static void main(String [] args){
		try{
			Connection conn = new Connection();
			
			System.out.println("java.library.path=" + System.getProperty("java.library.path"));
			conn.JcoTestCompany();
			
			
		}catch(Exception e){
			e.printStackTrace();
		}
	}

}
